home *** CD-ROM | disk | FTP | other *** search
- /* lock.c Handles the semaphore locking interface
-
- Copyright Feb. 1991, Peter Hardie VE5VA.
-
-
- The setbusy/clrbusy/getbusy/unbusy calls are used to protect the 'GM'
- and 'GU' commands so that only the sysop process running the 'GM'
- can be executing at the time that the 'GM' or 'GU' proceeds.
- Each process executes setbusy() when it is active and clrbusy when
- it is going to sleep again (in do_idle usually). A process that
- wants to do a 'GM' or 'GU' must first do a getbusy() which will either
- return a value of 1 to indicate failure or otherwise it is safe to
- proceed. When it has finished it must execute unbusy().
- This is equivalent to the classic case of the "multiple reader -
- single writer" problem.
-
- The begin_lock and end_lock calls are simple semaphores used to protect
- write calls into the files, mail.dat, bid.mb, and user.dat. They also
- protect the calls to generate the WP message and also the call to the
- stale() routine. In fmsg() they lock the message currently being
- forwarded.
- Ideally, the locks for each file could be different which would allow
- one user writing in the mail file to proceed even if another is causing
- a write into the bid file (for example). I may get around to creating a
- semaphore for each file once this code settles down a bit!
-
- */
-
-
- #include <exec/types.h>
- #include <exec/exec.h>
- #include <ctype.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "lock.h"
- extern int debug;
- /*
- struct Message *lock_msg;
- struct MsgPort *sema_lock;
- */
- struct Message *busy_msg,*mail_msg,*user_msg,*bid_msg;
- struct user_sem *sema_busy; /* Implementation of busy is a bit different
- than for lock. user_sem is a semaphore and
- a process counter.
- */
- struct file_sem *sema_mail = 0L,*sema_user = 0L, *sema_bid = 0L;
- /* Set up both semaphores */
- findlock()
- {
- /* set up and find the semaphores for begin_lock and end_lock.
- This does not need to look for the locker process as that has
- already been done and we are guaranteed that it exists.
- */
- /*
- lock_msg = AllocMem(sizeof(*lock_msg), MEMF_CLEAR | MEMF_PUBLIC);
- if(lock_msg == 0)return(1);
- lock_msg->mn_ReplyPort = CreatePort(0L,0L);
- sema_lock = FindPort(SEM_LOCK);
- if(sema_lock == 0) {
- stoplock();
- return(1);
- }
- */
- /* set up and find the semaphore for set/clr/get/unbusy */
-
- busy_msg = AllocMem(sizeof(*busy_msg), MEMF_CLEAR | MEMF_PUBLIC);
- if(busy_msg == 0)return(1);
- busy_msg->mn_ReplyPort = CreatePort(0L,0L);
- sema_busy = (struct user_sem *) FindPort(SEM_BUSY);
- if(sema_busy == 0) {
- stoplock();
- return(2);
- }
- /* Create the mail.dat semaphore */
- mail_msg = AllocMem(sizeof(*mail_msg), MEMF_CLEAR | MEMF_PUBLIC);
- if(mail_msg == 0)return(1);
- mail_msg->mn_ReplyPort = CreatePort(0L,0L);
- sema_mail = (struct file_sem *) FindPort(SEM_MAIL);
- if(sema_mail == 0) {
- stoplock();
- return(3);
- }
- /* Create the user.dat semaphore */
- user_msg = AllocMem(sizeof(*user_msg), MEMF_CLEAR | MEMF_PUBLIC);
- if(user_msg == 0)return(1);
- user_msg->mn_ReplyPort = CreatePort(0L,0L);
- sema_user = (struct file_sem *) FindPort(SEM_USER);
- if(sema_user == 0) {
- stoplock();
- return(4);
- }
-
- /* Create the bid.mb semaphore */
- bid_msg = AllocMem(sizeof(*bid_msg), MEMF_CLEAR | MEMF_PUBLIC);
- if(bid_msg == 0)return(1);
- bid_msg->mn_ReplyPort = CreatePort(0L,0L);
- sema_bid = (struct file_sem *) FindPort(SEM_BID);
- if(sema_bid == 0) {
- stoplock();
- return(5);
- }
- return(0);
- }
- stoplock()
- {
- /*
- if(lock_msg) {
- if(lock_msg->mn_ReplyPort)DeletePort(lock_msg->mn_ReplyPort);
- FreeMem(lock_msg,sizeof(*lock_msg));
- }
- */
- if(busy_msg) {
- if(busy_msg->mn_ReplyPort)DeletePort(busy_msg->mn_ReplyPort);
- FreeMem(busy_msg,sizeof(*busy_msg));
- }
- if(mail_msg) {
- if(mail_msg->mn_ReplyPort)DeletePort(mail_msg->mn_ReplyPort);
- FreeMem(mail_msg,sizeof(*mail_msg));
- }
- if(user_msg) {
- if(user_msg->mn_ReplyPort)DeletePort(user_msg->mn_ReplyPort);
- FreeMem(user_msg,sizeof(*user_msg));
- }
- if(bid_msg) {
- if(bid_msg->mn_ReplyPort)DeletePort(bid_msg->mn_ReplyPort);
- FreeMem(bid_msg,sizeof(*bid_msg));
- }
- }
-
- /* begin_lock and end_lock are not used in the multi-user CBBS any more
- so make them dummy routines
- */
- begin_lock()
- {
- /*
- if(Procure((struct Semaphore *)sema_lock,lock_msg) == 0) {
- WaitPort(lock_msg->mn_ReplyPort);
- GetMsg(lock_msg->mn_ReplyPort);
- }
- */
- }
- end_lock()
- {
- /*
- Vacate((struct Semaphore *)sema_lock);
- */
- }
-
- setbusy()
- {
- if(Procure((struct Semaphore *)sema_busy,busy_msg) == 0) {
- WaitPort(busy_msg->mn_ReplyPort);
- GetMsg(busy_msg->mn_ReplyPort);
- }
- sema_busy->count++;
- Vacate((struct Semaphore *)sema_busy);
- }
- clrbusy()
- {
- if(Procure((struct Semaphore *)sema_busy,busy_msg) == 0) {
- WaitPort(busy_msg->mn_ReplyPort);
- GetMsg(busy_msg->mn_ReplyPort);
- }
- sema_busy->count--;
- Vacate((struct Semaphore *)sema_busy);
- }
- /* This returns 1 if there's more than one user active (itself).
- The setbusy/clrbusy/getbusy/unbusy are used only to lock out users
- while either a 'GM' or 'GU' are being done.
- */
- getbusy()
- {
- if(Procure((struct Semaphore *)sema_busy,busy_msg) == 0) {
- WaitPort(busy_msg->mn_ReplyPort);
- GetMsg(busy_msg->mn_ReplyPort);
- }
- /* NOTE here that if the count is one, then we return success and
- do NOT Vacate the semaphore. The process MUST call unbusy() at
- a later time to clear the semaphore
- */
- if(sema_busy->count == 1) {
- return(0);
- }
-
- /* The count is wrong so just Vacate the semaphore and return failure
- */
- Vacate((struct Semaphore *)sema_busy);
- return(1);
- }
-
- unbusy()
- {
- Vacate((struct Semaphore *)sema_busy);
- }
- lock_bid()
- {
- if(Procure((struct Semaphore *)sema_bid,bid_msg) == 0) {
- WaitPort(bid_msg->mn_ReplyPort);
- GetMsg(bid_msg->mn_ReplyPort);
- }
- }
- unlock_bid()
- {
- Vacate((struct Semaphore *)sema_bid);
- }
- lock_user()
- {
- if(Procure((struct Semaphore *)sema_user,user_msg) == 0) {
- WaitPort(user_msg->mn_ReplyPort);
- GetMsg(user_msg->mn_ReplyPort);
- }
- }
- unlock_user()
- {
- Vacate((struct Semaphore *)sema_user);
- }
- /* Process must have the semaphore already to do these next two */
- set_user(i)
- long i;
- {
- sema_user->filesize = i;
- }
- long get_user()
- {
- return(sema_user->filesize);
- }
- lock_mail()
- {
- if(Procure((struct Semaphore *)sema_mail,mail_msg) == 0) {
- WaitPort(mail_msg->mn_ReplyPort);
- GetMsg(mail_msg->mn_ReplyPort);
- }
- }
- unlock_mail()
- {
- Vacate((struct Semaphore *)sema_mail);
- }
- set_mail(i)
- long i;
- {
- sema_mail->filesize = i;
- }
- long get_mail()
- {
- return(sema_mail->filesize);
- }
-